package lt.vu.mif.os;

import java.util.ArrayList;
import java.util.List;

import javax.swing.JOptionPane;

import lt.vu.mif.os.processes.JobGovernor;
import lt.vu.mif.os.processors.RealMachineProcessor;
import lt.vu.mif.os.resources.Console;
import lt.vu.mif.os.resources.Input;
import lt.vu.mif.os.resources.Resource;

/**
* Real machine class which launches virtual machine, when program is loaded.
* 
* @author Antanas Rudaitis
* @author Laurynas Paradauskas
* @author Algirdas Šaltupis
* 
*/

public class RealMachine {

    private static RealMachineProcessor rmp = new RealMachineProcessor();
    public static RealMachineFrame rmFrame;
    public static JobGovernor jobgov = new JobGovernor();
    public static Console console = new Console();
    public static Input input = new Input();
    public static Resource processor = new Resource();
    public int dataStartIndex;
    public int codeStartIndex;
    public int dataEndIndex;
    public int codeEndIndex;
    private static List<VirtualMachine> vmList = new ArrayList<VirtualMachine>();
    private static int vmCounter;
    /**
    *
    * Real Machine gets ready to work, opens GUI
    * 
    */
    public static void init() {

      rmFrame = new RealMachineFrame(new javax.swing.JFrame("RealMachine"), true);
      rmp.registers.updateGUIReg(rmFrame);
      rmFrame.addWindowListener(new java.awt.event.WindowAdapter() {
          @Override
          public void windowClosing(java.awt.event.WindowEvent e) {
              System.exit(0);
          }
      });
      rmFrame.setVisible(true);
      vmCounter = 0;
      rmFrame.updateVMCounterField(vmCounter);
//      rmFrame.addNewProcess("JobGovernor", jobgov.getState());
    }
    /**
	 * Excludes memory cells for virtual machine
	 */
    public void excludeVMCodeCells() {	
    	codeStartIndex = 0;
    	codeEndIndex = 127;
    }
	/**
	 * Excludes memory cells for virtual machine data
	 */
    public void excludeVMDataCells() {
    	dataStartIndex = codeEndIndex + 1;
    	dataEndIndex = dataStartIndex + 127;
    	
    }
    public static void setSI(byte si) {
    	rmp.registers.setSi(si);
    	rmFrame.updateSIField(Byte.toString(si));
//    	if (si==1) {
//    		String input = (String)JOptionPane.showInputDialog(null,"Enter text: ", "INPUT WINDOW", 1);
//    		rmp.stack.add(input);
//    	}
    }
    
    public static void setPI(byte pi) {
    	rmp.registers.setPi(pi);
    	rmFrame.updatePIField(Byte.toString(pi));
    	switch (pi) {
    		case 1:	JOptionPane.showMessageDialog(null, "Undefinied command"); 
    			break;
    		case 2: JOptionPane.showMessageDialog(null, "Divide from zero");
    			break;
    		default:
    			JOptionPane.showMessageDialog(null, "Undefinied interrupt");
    	}
    }
    public static Object getFromStack() {
    	return rmp.stack.pop();
    }
    public static void setMode(boolean mode) {
    	rmp.registers.setMode(mode);
    	rmFrame.updateModeField(Boolean.toString(mode));
    }
    
    public static void incVMCounter() {
        vmCounter++;
        rmFrame.updateVMCounterField(vmCounter);
    }
    
    public static void decVMCounter() {
        vmCounter--;
        rmFrame.updateVMCounterField(vmCounter);
    }
    
    public static int getVMCounter() {
        return vmCounter;
    }
    
    public static void print(String string) {
        rmFrame.printToConsole(string);
    }
    
    public static void addVm(VirtualMachine vm) {
        vmList.add(vm);
    }
    
    public static VirtualMachine getVm(int id) {
        return vmList.get(id-1);
    }
    
    public static List<VirtualMachine> getAllVm() {
        return vmList;
    }
    
    public static void setRMP(RealMachineProcessor r) {
        rmp = r;
    }
    
    public static RealMachineProcessor getRMP() {
        return rmp;
    }
    
    public static void addToStack(String str) {
        rmp.stack.add(str);
    }
    
    public static void setTimer(int i) {
        rmp.registers.setTi(i);
    }
}
